package com.td.filemanager.utils;

import com.td.filemanager.MyApplication;
import ohos.aafwk.ability.Lifecycle;
import ohos.aafwk.ability.LifecycleStateObserver;
import ohos.aafwk.content.Intent;
import ohos.app.Context;
import ohos.app.dispatcher.TaskDispatcher;
import ohos.app.dispatcher.task.Revocable;
import ohos.app.dispatcher.task.TaskPriority;
import ohos.utils.LightweightSet;

import java.util.Objects;
import java.util.function.BooleanSupplier;
import java.util.function.Supplier;

/**
 * 异步任务切换工具类
 *
 * @since 2021/10/9 15:05
 */
public class TaskUtil implements LifecycleStateObserver {
    private static final String TAG = TaskUtil.class.getName();
    private final TaskDispatcher mTaskDispatcher;
    private final LightweightSet<Revocable> mRevocSet = new LightweightSet<>();

    public TaskUtil(Context context) {
        this(context, null);
    }

    public TaskUtil(Context context, Lifecycle lifecycle) {
        mTaskDispatcher = context.createParallelTaskDispatcher(TAG, TaskPriority.DEFAULT);
        if (Objects.nonNull(lifecycle)) {
            lifecycle.addObserver(this);
        }
    }

    /**
     * 执行带返回值的任务，并在主线程返回
     *
     * @param supplier 函数式接口，无输入，返回T
     * @param callBack 主线程的回调结果
     * @param <T>      T
     */
    public <T> void doTask(Supplier<T> supplier, ResultCallBack<T> callBack) {
        Revocable revocable = mTaskDispatcher.asyncDispatch(() -> {
            T mClass = supplier.get();
            if (Objects.nonNull(callBack)) {
                Revocable asyncDispatch = MyApplication.getInstance().getUITaskDispatcher().asyncDispatch(() -> callBack.onCall(mClass));
                mRevocSet.add(asyncDispatch);
            }
        });
        mRevocSet.add(revocable);
    }

    /**
     * 执行带Boolean返回值的任务，并在主线程返回
     *
     * @param supplier 函数式接口，无输入，返回Boolean
     * @param callBack 主线程的回调结果
     */
    public void doTask(BooleanSupplier supplier, CallBack callBack) {
        Revocable revocable = mTaskDispatcher.asyncDispatch(() -> {
            boolean result = supplier.getAsBoolean();
            if (Objects.nonNull(callBack)) {
                Revocable asyncDispatch = MyApplication.getInstance().getUITaskDispatcher().asyncDispatch(() -> {
                    callBack.onCall(result);
                });
                mRevocSet.add(asyncDispatch);
            }
        });
        mRevocSet.add(revocable);
    }

    /**
     * 执行无返回值的任务，并在主线程返回
     *
     * @param consumer 函数式接口，无输入，无返回值
     * @param callBack 主线程的回调结果
     */
    public void doTask(VoidConsumer consumer, CallBack callBack) {
        Revocable revocable = mTaskDispatcher.asyncDispatch(() -> {
            try {
                consumer.complete();
                if (Objects.nonNull(callBack)) {
                    Revocable asyncDispatch = MyApplication.getInstance().getUITaskDispatcher().asyncDispatch(() -> callBack.onCall(true));
                    mRevocSet.add(asyncDispatch);
                }
            } catch (Exception e) {
                e.printStackTrace();
                if (Objects.nonNull(callBack)) {
                    Revocable asyncDispatch = MyApplication.getInstance().getUITaskDispatcher().asyncDispatch(() -> callBack.onCall(false));
                    mRevocSet.add(asyncDispatch);
                }
            }
        });
        mRevocSet.add(revocable);
    }

    @Override
    public void onStateChanged(Lifecycle.Event event, Intent intent) {
        if (event == Lifecycle.Event.ON_STOP) {
            cancel();
        }
    }

    private void cancel() {
        mRevocSet.forEach(Revocable::revoke);
    }

    /**
     * 带返回值的回调
     *
     * @param <T>
     */
    public interface ResultCallBack<T> {
        void onCall(T mClass);
    }

    /**
     * 返回成功或失败的接口
     */
    public interface CallBack {
        void onCall(boolean result);
    }

    /**
     * 自定义函数式接口，无输入，无返回值
     */
    @FunctionalInterface
    public interface VoidConsumer {
        void complete();
    }
}
